/*******************************************************************************
 * @(#)WebSSOManager1.java 2018年09月24日 12:42
 * Copyright 2018 upbos.com. All rights reserved.
 *******************************************************************************/
package com.upbos.sso.mgr;

import com.upbos.sso.Constants;
import com.upbos.sso.entity.SsoUser;
import com.upbos.sso.entity.Token;
import com.upbos.sso.entity.TokenType;
import com.upbos.sso.storage.StorageManager;
import com.upbos.sso.SsoManager;
import com.upbos.sso.cookie.CookieManager;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <b>Application name：</b> WebSsoManager.java <br>
 * <b>Application describing： </b> <br>
 * <b>Copyright：</b> Copyright &copy; 2018 upbos.com 版权所有。<br>
 * <b>Company：</b> upbos.com <br>
 * <b>Date：</b> 2018年09月24日 12:42 <br>
 * <b>@author：</b> <a href="mailto:wangjz@miyzh.com"> wangjz </a> <br>
 * <b>version：</b>V1.0.0 <br>
 */

@Slf4j
public class SsoManagerImpl implements SsoManager {


    private StorageManager storageManager;


    private CookieManager cookieManager;

    public void setCookieManager(CookieManager cookieManager) {
        this.cookieManager = cookieManager;
    }

    public void setStorageManager(StorageManager storageManager) {
        this.storageManager = storageManager;
    }

    @Override
    public Token login(HttpServletRequest request, HttpServletResponse response, SsoUser ssoUser) {
        return this.login(request, response, ssoUser, TokenType.WEB);
    }

    @Override
    public Token login(HttpServletRequest request, HttpServletResponse response, SsoUser ssoUser, TokenType tokenType) {
        return this.login(request, response, ssoUser, tokenType.getValue());
    }

    @Override
    public Token login(HttpServletRequest request, HttpServletResponse response, SsoUser ssoUser, String tokenType) {
        Token token = getToken(request);

        if (token == null) {
            token = Token.generateToken(request, ssoUser.getUid(), tokenType);
            cookieManager.setCookie(response, token.getId());
            storageManager.saveToken(token);
            storageManager.saveSsoUser(token.getId(), ssoUser);
        }

        return token;
    }

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response) {
        String tokenId = cookieManager.getTokenId(request);
        if (tokenId != null) {
            storageManager.removeToken(tokenId);
            cookieManager.removeCookie(response);
        }
    }

    @Override
    public Token getToken(String tokenId) {
        return storageManager.getToken(tokenId);
    }

    @Override
    public Token getToken(HttpServletRequest request) {
        String tokenId = cookieManager.getTokenId(request);
        if (tokenId == null) {
            tokenId = request.getHeader(Constants.TOKEN_ID_COOKIE_NAME);
        }
        return tokenId == null ? null : storageManager.getToken(tokenId);
    }

    @Override
    public boolean validateToken(HttpServletRequest request) {
        String tokenId = cookieManager.getTokenId(request);
        return tokenId == null ? false : storageManager.existToken(tokenId);
    }

    @Override
    public SsoUser getSsoUser(HttpServletRequest request) {
        Token token = getToken(request);
        return storageManager.getSsoUser(token.getId());
    }

    @Override
    public SsoUser getSsoUser(String tokenId) {
        return storageManager.getSsoUser(tokenId);
    }

    @Override
    public void setAttr(HttpServletRequest request, String key, Object value) {
        Token token = getToken(request);
        if (token != null) {
            storageManager.setAttr(token.getId(), key, value);
        }
    }

    @Override
    public void setAttr(String tokenId, String key, Object value) {
        Token token = getToken(tokenId);
        if (token != null) {
            storageManager.setAttr(token.getId(), key, value);
        }
    }

    @Override
    public <T> T getAttr(HttpServletRequest request, String key) {
        Token token = getToken(request);
        return token == null ? null : storageManager.getAttr(token.getId(), key);
    }

    @Override
    public <T> T getAttr(String tokenId, String key) {
        return storageManager.getAttr(tokenId, key);
    }

    @Override
    public void removeAttr(HttpServletRequest request, String key) {
        Token token = getToken(request);
        if (token != null) {
            storageManager.removeAttr(token.getId(), key);
        }
    }

    @Override
    public CookieManager getCookieManager() {
        return this.cookieManager;
    }
}